package dao

import (
	"context"
	"wxpay/internal/model"
	"wxpay/pkg/merrors"

	"github.com/nsqio/go-nsq"
	"github.com/patrickmn/go-cache"
	"gorm.io/gorm"
)

type Withdraw interface {
	// 创建二级商户提现申请
	SaveSubMchWithDraw(ctx context.Context, tx *gorm.DB, m *model.SubMchWithdraw) error
	// 根据业务单号查询二级商户提现申请
	QuerySubMchWithDrawByBizNo(ctx context.Context, db *gorm.DB, bizNo string) (t *model.SubMchWithdraw, err error)
	// 根据out_request_no查询二级商户提现申请
	QuerySubMchWithDrawByOutNo(ctx context.Context, db *gorm.DB, outNo string) (t *model.SubMchWithdraw, err error)
}

type withdrawRepo struct {
	*gorm.DB
	producer *nsq.Producer
	cache    *cache.Cache
}

func NewWithdrawRepo(d *gorm.DB, p *nsq.Producer, c *cache.Cache) *withdrawRepo {
	return &withdrawRepo{d, p, c}
}

func (w *withdrawRepo) SaveSubMchWithDraw(ctx context.Context, tx *gorm.DB, m *model.SubMchWithdraw) error {
	const op merrors.Op = "withdrawRepo.SaveSubMchWithDraw"
	if e := tx.Save(m).Error; e != nil {
		return merrors.E(op, merrors.DBError, merrors.ErrInternal, e)
	}
	return nil
}

func (w *withdrawRepo) QuerySubMchWithDrawByBizNo(ctx context.Context, db *gorm.DB, bizNo string) (t *model.SubMchWithdraw, err error) {
	const op merrors.Op = "withdrawRepo.QuerySubMchWithDrawByBizNo"
	res := model.SubMchWithdraw{}
	if err := db.Model(&model.SubMchWithdraw{}).Where("biz_withdraw_id = ?", bizNo).First(&res).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, merrors.E(op, merrors.NotExist, merrors.ErrNotFound, err)
		} else {
			return nil, merrors.E(op, merrors.DBError, merrors.ErrInternal, err)
		}

	}
	t = &res
	return
}

func (w *withdrawRepo) QuerySubMchWithDrawByOutNo(ctx context.Context, db *gorm.DB, outNo string) (t *model.SubMchWithdraw, err error) {
	const op merrors.Op = "withdrawRepo.QuerySubMchWithDrawByOutNo"
	res := model.SubMchWithdraw{}
	if err := db.Model(&model.SubMchWithdraw{}).Where("out_request_no = ?", outNo).First(&res).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, merrors.E(op, merrors.NotExist, merrors.ErrNotFound, err)
		} else {
			return nil, merrors.E(op, merrors.DBError, merrors.ErrInternal, err)
		}

	}
	t = &res
	return
}
